package com.dkd.sbtz.service.impl;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.dkd.common.exception.ServiceException;
import com.dkd.common.utils.DateUtils;
import com.dkd.common.utils.SecurityUtils;
import com.dkd.common.utils.StringUtils;
import com.dkd.sbtz.domain.AssetSpareVariant;
import com.dkd.sbtz.domain.Sbtz;
import com.dkd.sbtz.domain.vo.AssetNodeListVO;
import com.dkd.sbtz.domain.vo.spare.SpareBatchDTO;
import com.dkd.sbtz.domain.vo.spare.SparePlanInfoDTO;
import com.dkd.sbtz.domain.vo.spare.SpareVO;
import com.dkd.sbtz.domain.vo.spare.SpecialItemDTO;
import com.dkd.sbtz.service.ISbtzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dkd.sbtz.mapper.SpareMapper;
import com.dkd.sbtz.domain.Spare;
import com.dkd.sbtz.service.ISpareService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 备件库存Service业务层处理
 * 
 * @author xzj
 * @date 2025-09-03
 */
@Service
public class SpareServiceImpl implements ISpareService
{
    @Autowired
    private SpareMapper spareMapper;

    @Autowired
    private ISbtzService sbtzService;
    /**
     * 查询备件库存
     * 
     * @param id 备件库存主键
     * @return 备件库存
     */
    @Override
    public Spare selectSpareById(Long id)
    {
        return spareMapper.selectSpareById(id);
    }



    /**
     * 新增备件库存
     * 
     * @param spare 备件库存
     * @return 结果
     */
    @Override
    public int insertSpare(Spare spare)
    {
        spare.setCreateTime(DateUtils.getNowDate());
        return spareMapper.insertSpare(spare);
    }

    /**
     * 修改备件库存
     * 
     * @param spare 备件库存
     * @return 结果
     */
    @Override
    public int updateSpare(Spare spare)
    {
        spare.setUpdateTime(DateUtils.getNowDate());
        return spareMapper.updateSpare(spare);
    }

    /**
     * 批量删除备件库存
     * 
     * @param ids 需要删除的备件库存主键
     * @return 结果
     */
    @Override
    public int deleteSpareByIds(Long[] ids)
    {
        return spareMapper.deleteSpareByLongIds(ids);
    }

    /**
     * 删除备件库存信息
     * 
     * @param id 备件库存主键
     * @return 结果
     */
    @Override
    public int deleteSpareById(Long id)
    {
        return spareMapper.deleteSpareById(id);
    }


    @Override
    public List<Spare> list(String keyword) {
        return spareMapper.selectList(keyword);
    }

    @Override
    public List<Spare> listByIds(List<Long> ids) {
        return spareMapper.selectByIds(ids);
    }





    @Override
    @Transactional(rollbackFor = Exception.class)
    public int[] batchUpsert(List<SpareBatchDTO> items, String operator) {
        if (items == null || items.isEmpty()) throw new ServiceException("提交数据为空");

        // 1) 预处理/校验
        List<SpareBatchDTO> cleaned = items.stream().map(this::cleanOne).collect(Collectors.toList());

        // 同 code 的 name 必须一致
        Map<String, String> nameByCode = new HashMap<>();
        for (SpareBatchDTO it : cleaned) {
            String code = it.getCode();
            String name = it.getName();
            if (!nameByCode.containsKey(code)) nameByCode.put(code, name);
            else if (!name.equals(nameByCode.get(code))) {
                throw new ServiceException("编码 " + code + " 的名称不一致");
            }
        }

        // 2) 读已存在
        List<String> codes = cleaned.stream().map(SpareBatchDTO::getCode).distinct().collect(Collectors.toList());
        Map<String, Spare> existed = spareMapper.selectByCodes(codes)
                .stream().collect(Collectors.toMap(Spare::getCode, x -> x));

        int created = 0, updated = 0, variantsUpsert = 0;
        List<AssetSpareVariant> variantsToUpsert = new ArrayList<>();

        // 3) 逐个 upsert
        for (SpareBatchDTO it : cleaned) {
            Spare s = existed.get(it.getCode());
            if (s == null) {
                // insert
                s = new Spare();
                s.setCode(it.getCode());
                s.setName(it.getName());
                s.setUnit(nvl(it.getUnit(), ""));
                s.setIsSpecial(nvl(it.getType(), 0));
                s.setStatus(nvl(it.getStatus(), 0));
                s.setStockTotal(nvl(it.getStockTotal(), 0L));
                s.setStockAvailable(nvl(it.getStockAvailable(), 0L));
                s.setRemark(nvl(it.getRemark(), ""));
                s.setPlanDate(it.getPlanDate());
                s.setOrderDate(it.getOrderDate());
                s.setCreateBy(operator);
                spareMapper.insertSpare(s);
                existed.put(s.getCode(), s);
                created++;
            } else {
                // update（按需覆盖）
                s.setName(it.getName());
                s.setUnit(nvl(it.getUnit(), s.getUnit()));
                s.setIsSpecial(nvl(it.getType(), s.getIsSpecial()));
                s.setStatus(nvl(it.getStatus(), s.getStatus()));
                s.setStockTotal(nvl(it.getStockTotal(), s.getStockTotal()));
                s.setStockAvailable(nvl(it.getStockAvailable(), s.getStockAvailable()));
                s.setRemark(nvl(it.getRemark(), s.getRemark()));
                s.setPlanDate(it.getPlanDate());
                s.setOrderDate(it.getOrderDate());
                s.setUpdateBy(operator);
                spareMapper.updateSpare(s);
                updated++;
            }

            // 组装 variants
            if (it.getVariants() != null && !it.getVariants().isEmpty()) {
                for (SpareBatchDTO.SpareVariantItem v : it.getVariants()) {
                    if (StringUtils.isEmpty(v.getSpec()) && StringUtils.isEmpty(v.getVendor())) continue;
                    AssetSpareVariant one = new AssetSpareVariant();
                    one.setSpareId(s.getId());
                    one.setSpec(nvl(v.getSpec(), ""));
                    one.setVendor(nvl(v.getVendor(), ""));
                    one.setStatus(nvl(v.getStatus(), s.getStatus()));
                    one.setCreateBy(operator);
                    variantsToUpsert.add(one);
                }
            }
        }

        // 4) 批量 upsert 规格
        if (!variantsToUpsert.isEmpty()) {
            variantsUpsert = spareMapper.batchInsertOrUpdateVariants(variantsToUpsert);
            // MySQL 返回的是受影响行数（含更新），这里按记录数估算：
            variantsUpsert = variantsToUpsert.size();
        }

        return new int[]{created, updated, variantsUpsert};
    }

    private SpareBatchDTO cleanOne(SpareBatchDTO x) {
        if (x == null) throw new ServiceException("出现空对象");
        x.setCode(req(x.getCode()).toUpperCase()); // 统一大写
        x.setName(req(x.getName()));
        x.setUnit(nvl(x.getUnit(), ""));
        x.setType(nvl(x.getType(), 0));
        x.setStatus(nvl(x.getStatus(), 0));
        x.setStockTotal(nvl(x.getStockTotal(), 0L));
        x.setStockAvailable(nvl(x.getStockAvailable(), 0L));
        if (x.getVariants() != null) {
            x.setVariants(
                    x.getVariants().stream().filter(Objects::nonNull).collect(Collectors.toList())
            );
        }
        return x;
    }

    private static String req(String s) {
        if (s == null || s.trim().isEmpty()) throw new ServiceException("必填字段为空");
        return s.trim();
    }
    private static <T> T nvl(T v, T dft) { return v == null ? dft : v; }






    @Override
    public List<SpareVO> selectSpareList(Spare q) {
        // 这里外层已调用 startPage()
        List<SpareVO> list = spareMapper.selectSpareList(q);
        if (list == null || list.isEmpty()) return list;

        List<Long> ids = list.stream().map(SpareVO::getId).toList();
        List<AssetSpareVariant> allVar = spareMapper.selectVariantsBySpareIds(ids);
        Map<Long, List<AssetSpareVariant>> map = allVar.stream()
                .collect(Collectors.groupingBy(AssetSpareVariant::getSpareId));


        // ② 再查计划关系
        List<SparePlanInfoDTO> planRows = spareMapper.selectPlanInfosBySpareIds(ids);
        Map<Long, List<SparePlanInfoDTO>> planMap = planRows.stream()
                .collect(Collectors.groupingBy(SparePlanInfoDTO::getSpareId));

        for (SpareVO s : list) {
            List<AssetSpareVariant> v = map.getOrDefault(s.getId(), Collections.emptyList());
            s.setVariants(v);
            s.setVariantCount(v.size());
            s.setVariantsText(v.stream()
                    .map(x -> (Optional.ofNullable(x.getSpec()).orElse(""))
                            + (StringUtils.isNotEmpty(x.getVendor()) ? " / " + x.getVendor() : ""))
                    .collect(Collectors.joining("、")));

            s.setPlanInfos(planMap.getOrDefault(s.getId(), Collections.emptyList()));
        }
        return list;
    }



    @Override
    public SpareVO getDetail(Long id) {
        SpareVO vo = spareMapper.selectSpareVOById(id);
        if (vo == null) throw new ServiceException("记录不存在");
        return vo;
    }


    private String generateNextCodeByType() {
        String nodeType = "SPARE";
        String maxCode = spareMapper.getMaxCodeByType(nodeType); // 假设 mapper 有此方法，返回如 "MACHINE0000005"
        long nextNum = 1L;
        if (StringUtils.isNotBlank(maxCode)) {
            // 解析数字部分（如从 "MACHINE0000005" 提取 5）
            String numStr = maxCode.replaceAll("^" + Pattern.quote(nodeType), "").replaceAll("^0+", "");
            if (StringUtils.isNotBlank(numStr)) {
                nextNum = Long.parseLong(numStr) + 1;
            }
        }
        // 格式化：nodeType + 7位0填充数字
        String numFormatted = String.format("%07d", nextNum);
        String newCode = nodeType + numFormatted;

        // 确保唯一：如果已存在，继续 +1（递归或循环）
        while (spareMapper.existsByCode(newCode)) {
            nextNum++;
            numFormatted = String.format("%07d", nextNum);
            newCode = nodeType + numFormatted;
        }
        return newCode;
    }
    /** 新增：主表 + 规格批量 */
    @Override @Transactional(rollbackFor = Exception.class)
    public int insertSpareWithVariants(SpareVO vo) {

        String sha256Hash = sbtzService.processAssetHash(
                vo.getSpecification(),
                vo.getModel(),
                vo.getMaterial(),
                vo.getBrand(),
                vo.getManufacturer()
        );

        Spare spareInfo = spareMapper.selectByHash(sha256Hash);
        if(spareInfo != null){
            Long minStock = spareInfo.getMinStock();
        }


        String username = SecurityUtils.getUsername();
        String code = vo.getCode();
        if (StringUtils.isBlank(code)){
            code = generateNextCodeByType();
        }
        // 1) 插入 spare
        Spare s = new Spare();
        s.setCode(code);
        s.setName(vo.getName());
        s.setUnit("个");
        s.setStockTotal(vo.getStockTotal());
        s.setStockAvailable(vo.getStockAvailable());
        s.setIsSpecial(vo.getIsSpecial());
//        s.setStatus(vo.getStatus());

        s.setRemark(vo.getRemark());
        s.setOrderDate(vo.getOrderDate());
        s.setMinStock(vo.getMinStock());
        s.setMaxStock(vo.getMaxStock());

        s.setSpecification(vo.getSpecification());
        s.setModel(vo.getModel());
        s.setMaterial(vo.getMaterial());
        s.setDesignTemp(vo.getDesignTemp());
        s.setDesignPress(vo.getDesignPress());
        s.setMotorPower(vo.getMotorPower());
        s.setSpareClass(vo.getSpareClass());
        s.setBrand(vo.getBrand());
        s.setManufacturer(vo.getManufacturer());


//        s.setAmount(vo.getAmount());
//        s.setAmountUnit(vo.getAmountUnit());
        s.setCreateBy(username);
        s.setCreateTime(new Date());
        s.setHash(sha256Hash);
        int n = spareMapper.insertSpare(s);

        // 2) 批量插入 variants（过滤空行）
        //vo.setId(s.getId());
//        if (vo.getVariants() != null && !vo.getVariants().isEmpty()) {
//            List<AssetSpareVariant> list = vo.getVariants().stream()
//                    .filter(v -> (v.getSpec()!=null && !v.getSpec().trim().isEmpty())
//                            || (v.getVendor()!=null && !v.getVendor().trim().isEmpty()))
//                    .peek(v -> { v.setSpareId(s.getId()); v.setCreateBy(vo.getCreateBy()); })
//                    .toList();
//            if (!list.isEmpty()) spareMapper.batchInsertVariants(list);
//        }
        return n;
    }

    /** 修改：主表 + 重置规格（简单策略：删原有后重插） */
    @Override @Transactional(rollbackFor = Exception.class)
    public int updateSpareWithVariants(SpareVO vo) {
        Objects.requireNonNull(vo.getId(), "缺少ID");
        String username = SecurityUtils.getUsername();
        String sha256Hash = sbtzService.processAssetHash(
                vo.getSpecification(),
                vo.getModel(),
                vo.getMaterial(),
                vo.getBrand(),
                vo.getManufacturer()
        );
        // 1) 更新主表
        Spare s = new Spare();
        s.setId(vo.getId());
        s.setName(vo.getName());
        s.setUnit("个");
        s.setMinStock(vo.getMinStock());
        s.setMaxStock(vo.getMaxStock());
        s.setStockTotal(vo.getStockTotal());
        s.setStockAvailable(vo.getStockAvailable());
        s.setIsSpecial(vo.getIsSpecial());
//        s.setStatus(vo.getStatus());
        s.setRemark(vo.getRemark());
        s.setOrderDate(vo.getOrderDate());

        s.setSpecification(vo.getSpecification());
        s.setModel(vo.getModel());
        s.setMaterial(vo.getMaterial());
        s.setDesignTemp(vo.getDesignTemp());
        s.setDesignPress(vo.getDesignPress());
        s.setMotorPower(vo.getMotorPower());
        s.setSpareClass(vo.getSpareClass());

        s.setBrand(vo.getBrand());
        s.setManufacturer(vo.getManufacturer());
        s.setUpdateBy(username);
        s.setUpdateTime(new Date());
        s.setHash(sha256Hash);
        int n = spareMapper.updateSpare(s);

        // 2) 规格：简单做法 = 全删再插（够用、逻辑清晰）
//        spareMapper.deleteVariantsBySpareId(vo.getId());
//        if (vo.getVariants() != null && !vo.getVariants().isEmpty()) {
//            List<AssetSpareVariant> list = vo.getVariants().stream()
//                    .filter(v -> (v.getSpec()!=null && !v.getSpec().trim().isEmpty())
//                            || (v.getVendor()!=null && !v.getVendor().trim().isEmpty()))
//                    .peek(v -> { v.setSpareId(vo.getId()); v.setCreateBy(vo.getUpdateBy()); })
//                    .toList();
//            if (!list.isEmpty()) spareMapper.batchInsertVariants(list);
//        }
        return n;
    }



    @Override
    public List<String> selectVendorsBySpareId(Long spareId) {
        return spareMapper.selectVendorsBySpareId(spareId);
    }

    @Override
    public List<String> selectSpecsBySpareVendor(Long spareId, String vendor) {
        return spareMapper.selectSpecsBySpareVendor(spareId, vendor);
    }

}
